#include "mainwindow.h"
#include <QPixmap>
#include <QMouseEvent>
#include <QDebug>
#include <windows.h>
#include <QString>
#include <QJsonDocument>
#include <QJsonArray>
#include "./ui_mainwindow.h"
#include <QComboBox>
#include <QNetworkReply>
#include <QListView>

QString style1 = "QPushButton{"
        "background-color:#f0f0f0;"//设置按钮背景色
        "border-radius:0px;"//设置圆角半径
        "color:black;"//设置按钮字体颜色
        "}"
        //鼠标悬停样式
        "QPushButton:hover{"
        "background-color:#e0e0e0;"
        "color:black;"
        "}";
QString style2 = "QPushButton{"
        "background-color:#ffffff;"
        "border-radius:0px;"
        "color:black;"
        "}"
        "QPushButton:hover{"
        "background-color:#e0e0e0;"
        "color:black;"
        "}";
QString style3 = "QPushButton{"
        "background-color:#fafafa;"
        "border-radius:8px;"
        "color:black;"
        "}"
        "QPushButton:hover{"
        "background-color:#e0e0e0;"
        "color:black;"
        "}";
QString style4 = "QPushButton{"
        "background-color:#fafafa;"
        "background-image: url(:/res/quit.png);"
        "border-radius:8px;"
        "color:black;"
        "}"
        "QPushButton:hover{"
        "background-color:#e0e0e0;"
        "color:black;"
        "}";

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setWindowFlags(Qt::Dialog|Qt::FramelessWindowHint);
    this->setFixedSize(QSize(768,868));
    //combo box
    ui->label_3->hide();
    ui->chooseMapComboBox->hide();
    ui->chooseMapComboBox->setStyleSheet("QComboBox {height: 26px;border-radius: 5px;border:none;background:#777777;color:white;}"
                                         "QComboBox {font:12pt 微软雅黑;}"
                                         "QComboBox QAbstractItemView {selection-background-color:#f1f1f1;selection-color:#000000; height: 25px;}"
                                         "QComboBox QAbstractItemView {border:none;background:#ffffff;outline: 0px;height: 25px;}"
                                         "QComboBox QAbstractItemView::item:selected {border:none;background:#e0e0e0;}"
                                         "QComboBox::drop-down{subcontrol-position: top right;width: 0px;}");
    ui->chooseMapComboBox->setView(new QListView);
    //button
    ui->configPage->setGeometry(50,0,100,100);
    ui->configPage->setStyleSheet(style2);
    ui->mapPage->setGeometry(150,0,100,100);
    ui->mapPage->setStyleSheet(style1);
    ui->connectLabel->setGeometry(300,0,200,100);
    ui->closeButton->setGeometry(650,25,50,50);
    ui->closeButton->setStyleSheet(style4);
    ui->connectButton->setStyleSheet(style3);
    //TilemapView
    tv = new TilemapView(this);
    tv->setGeometry(0,100,768,768);
    //stackedWidget
    ui->stackedWidget->addWidget(tv);
    ui->stackedWidget->setGeometry(0,100,768,768);
    //mqtt client
    ui->connectLabel->setText("disconnect.");
    is_connect = false;
    //http manager
    manager = new QNetworkAccessManager(this);

    need_move = false;

    connect(ui->connectButton, &QPushButton::clicked, this, &MainWindow::clickedConnectButton);
    connect(ui->port, &QLineEdit::returnPressed, ui->connectButton, &QPushButton::click);
    connect(ui->host, &QLineEdit::returnPressed, this, [=](){
        ui->port->setFocus();
    });
    connect(ui->configPage, &QPushButton::clicked, this, [=](){
        ui->stackedWidget->setCurrentIndex(0);
        ui->configPage->setStyleSheet(style2);
        ui->mapPage->setStyleSheet(style1);
    });
    connect(ui->mapPage, &QPushButton::clicked, this, [=](){
        ui->stackedWidget->setCurrentIndex(1);
        ui->mapPage->setStyleSheet(style2);
        ui->configPage->setStyleSheet(style1);
    });
}

MainWindow::~MainWindow()
{

}

void MainWindow::clickedConnectButton()
{
    if(is_connect){ //断开连接
        tv->pointcloud_thread.stop();
        ui->connectButton->setEnabled(false);
        ui->connectButton->setText("connect");
        ui->label_3->hide();
        ui->chooseMapComboBox->hide();
        ui->chooseMapComboBox->clear();
        ui->connectLabel->setText("disconnect.");
        ui->host->setReadOnly(false);
        ui->port->setReadOnly(false);
        client->disconnect();
        delete client;
        client = NULL;
        tv->clear();
        is_connect = false;
        ui->connectButton->setEnabled(true);
    }else {     //连接
        ui->connectButton->setText("disconnect");
        ui->connectLabel->setText("try to connect...");
        ui->host->setReadOnly(true);
        ui->port->setReadOnly(true);
        client = new QMqttClient(this);
        host = ui->host->text();
        port = ui->port->text();
        map_name = "cf-all-map-ts-R";
        client->setHostname(host);
        client->setPort(1883);
        client->setClientId("123456789");
        client->setUsername("xlx829");
        client->connectToHost();
        is_connect = true;
        connect(client, &QMqttClient::connected, this, &MainWindow::connected);
    }
}

void MainWindow::connected()
{
    ui->connectButton->setEnabled(false);

    //get设备id和产品id
    QNetworkReply* reply1 = manager->get(QNetworkRequest(QUrl("http://"+host+":"+port+"/v1/robot/mqtt")));
    QEventLoop loop1;
    connect(reply1, &QNetworkReply::finished, &loop1, &QEventLoop::quit);
    loop1.exec();
    QJsonObject jroot1;
    if(reply1->error()!=QNetworkReply::NoError){
        qDebug()<<"reply error:"<<reply1->errorString();
        ui->connectButton->setEnabled(true);
        return;
    }else{
        QJsonDocument doc = QJsonDocument::fromJson(reply1->readAll());
        jroot1 = doc.object();
    }
    reply1->deleteLater();
    robot_did = jroot1["did"].toString();
    robot_pid = jroot1["pid"].toString();

    //地图列表
    QNetworkReply* reply2 = manager->get(QNetworkRequest(QUrl("http://"+host+":"+port+"/v1/map/list")));
    QEventLoop loop2;
    connect(reply2, &QNetworkReply::finished, &loop2, &QEventLoop::quit);
    loop2.exec();
    QJsonObject jroot2;
    if(reply2->error()!=QNetworkReply::NoError){
        qDebug()<<"reply error:"<<reply2->errorString();
    }else{
        QJsonDocument doc = QJsonDocument::fromJson(reply2->readAll());
        jroot2 = doc.object();
    }
    reply2->deleteLater();
    connect(ui->chooseMapComboBox, &QComboBox::currentTextChanged, this, &MainWindow::viewInit);
    for(int i = 0; i < jroot2["states"].toArray().size(); i++) {
        if(jroot2["states"].toArray().at(i).toString()=="available") {
            ui->chooseMapComboBox->addItem(jroot2["maps"].toArray().at(i).toString());
        }
    }

    //点云
    tv->pointcloud_thread.setHostPort(host,port);
    connect(&tv->pointcloud_thread, &PointCloudThread::pointcloud, tv, &TilemapView::setPointCloud);
    tv->pointcloud_thread.start();

    ui->connectLabel->setText("connected!");
    ui->label_3->show();
    ui->chooseMapComboBox->show();
    ui->connectButton->setEnabled(true);
}

void MainWindow::viewInit(QString name)
{
    map_name = name;
    tv->init(host, port, map_name);
    subscribeMessage();
}

void MainWindow::subscribeMessage() //mqtt
{
    QMqttSubscription *sub1 = client->subscribe(QString("/"+robot_pid+"/"+robot_did+"/localization/pose"));
    QMqttSubscription *sub2 = client->subscribe(QString("/"+robot_pid+"/"+robot_did+"/planning/trajectory/2d/compact"));
    connect(sub1, &QMqttSubscription::messageReceived, this, &MainWindow::handleSubscribePoseMessage);
    connect(sub2, &QMqttSubscription::messageReceived, this, &MainWindow::handleSubscribeTrackMessage);
}

void MainWindow::handleSubscribePoseMessage(const QMqttMessage &msg)
{
    QJsonDocument qJsonDocument = QJsonDocument::fromJson(msg.payload());
    QJsonValue jroot = qJsonDocument.object();
    tv->setRobotPose(jroot["args"][0]["pose"]["xyz"][0].toDouble(),
            jroot["args"][0]["pose"]["xyz"][1].toDouble(),
            jroot["args"][0]["pose"]["rpy"][2].toDouble(),
            jroot["args"][0]["sequence"].toInt());
}

void MainWindow::handleSubscribeTrackMessage(const QMqttMessage &msg)
{
    QJsonDocument qJsonDocument = QJsonDocument::fromJson(msg.payload());
    QJsonValue jroot = qJsonDocument.object();
    tv->setTrack(jroot["args"][0]["trj"].toArray(),
            jroot["args"][0]["div"].toInt(),
            jroot["args"][0]["idx"].toArray());
}

void MainWindow::mousePressEvent(QMouseEvent * event)
{
    if(event->button()==Qt::LeftButton){
        m_pos = event->globalPos()-this->pos();
        if(m_pos.y()<100&&m_pos.x()>250&&m_pos.x()<650) {
            need_move = true;
        }
    }
}

void MainWindow::mouseMoveEvent(QMouseEvent * event)
{
    if(need_move){
        this->move(event->globalPos()-m_pos);
    }
}

void MainWindow::mouseReleaseEvent(QMouseEvent * event)
{
    need_move = false;
}
